#include <retro.h>
#include "retro.creator.h"

using namespace Retro::Creator::Dialog;
using namespace SPLib::Windows;

enum ChildWindows
{
  ChildOK         = 0x0100,
  ChildCancel
};

TCHAR textureTypes[][20] =
{
  _T("Image"),
  _T("Tileset"),
  _T("Animation")
};

Data::TextureType textureTypesVal[] =
{
  Data::TextureImage,
  Data::TextureTileset,
  Data::TextureAnimation
};

#define RETRO_TEXTUREBUTTON_ID  0x0100

VOID    EditTexture::onUnload()
{
  delete newBitmap;
  picTexture.setTexture(NULL);
}

VOID    EditTexture::onLoad()
{
  picTexture.create(*this);

  memset(&open, 0, sizeof(open));
  open.lStructSize    = sizeof(open);
  open.hwndOwner      = *this;
  open.lpstrFile      = path;
  open.lpstrFile[0]   = '\0';
  open.nMaxFile       = MAX_PATH;
  open.lpstrFilter    = _T("Images\0*.jpg;*.png;*.bmp;*.tga\0");
  open.nFilterIndex   = 1;
  open.lpstrTitle     = _T("Please select a texture image...");
  open.Flags          = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST |
    OFN_NOCHANGEDIR;

  {
    lblType.create(*this, _T("Type:"));
    lblType.setFont(getGdipFont());
    lblType.setBackColor(RETRO_DIALOG_BKCOLOR);

    hComboType = CreateWindow(WC_COMBOBOX, _T(""),
      CBS_DROPDOWN | CBS_HASSTRINGS | CBS_DROPDOWNLIST |
      WS_CHILD | WS_OVERLAPPED | WS_VISIBLE | WS_TABSTOP,
      0, 0, 0, 0, *this, NULL, getInstance(), NULL);

    ComboBox_AddStrings(hComboType, textureTypes);
    SetWindowFont(hComboType, getGdiFont(), FALSE);
  }

  {
    hEditData1 = CreateWindowEx(
      WS_EX_LEFT | WS_EX_CLIENTEDGE | WS_EX_CONTEXTHELP,
      WC_EDIT, _T(""), WS_CHILD | WS_TABSTOP |
      ES_NUMBER | ES_LEFT | ES_AUTOHSCROLL | ES_WANTRETURN,
      0, 0, 0, 0, *this, NULL, getInstance(), NULL);
    hEditData2 = CreateWindowEx(
      WS_EX_LEFT | WS_EX_CLIENTEDGE | WS_EX_CONTEXTHELP,
      WC_EDIT, _T(""), WS_CHILD | WS_TABSTOP |
      ES_NUMBER | ES_LEFT | ES_AUTOHSCROLL | ES_WANTRETURN,
      0, 0, 0, 0, *this, NULL, getInstance(), NULL);

    hUpDownData1 = CreateWindowEx(
      WS_EX_LEFT | WS_EX_LTRREADING, UPDOWN_CLASS, _T(""),
      WS_CHILD | UDS_ARROWKEYS | UDS_HOTTRACK | UDS_SETBUDDYINT,
      0, 0, 0, 0, *this, NULL, getInstance(), NULL);

    hUpDownData2 = CreateWindowEx(
      WS_EX_LEFT | WS_EX_LTRREADING, UPDOWN_CLASS, _T(""),
      WS_CHILD | UDS_ARROWKEYS | UDS_HOTTRACK | UDS_SETBUDDYINT,
      0, 0, 0, 0, *this, NULL, getInstance(), NULL);

    lblData1.create(*this);
    lblData1.setFont(getGdipFont());
    lblData1.setBackColor(RETRO_DIALOG_BKCOLOR);

    lblData2.create(*this);
    lblData2.setFont(getGdipFont());
    lblData2.setBackColor(RETRO_DIALOG_BKCOLOR);

    SetWindowFont(hEditData1, getGdiFont(), FALSE);
    SetWindowFont(hEditData2, getGdiFont(), FALSE);

    SendMessage(hUpDownData1, UDM_SETBUDDY, (WPARAM)hEditData1, 0);
    SendMessage(hUpDownData2, UDM_SETBUDDY, (WPARAM)hEditData2, 0);
  }

  addEdit(hEditName, lblName, _T("Name:"));
  addPath(hEditPath, lblPath, btnPath, _T("Path:"), RETRO_TEXTUREBUTTON_ID);

  sepData.create(*this);
  sepData.setOrientation(Geom::OrientationVertical);

  Edit_SetReadOnly(hEditPath, TRUE);

  LayoutElement* panel = getLayout().addFill(0, 256);
  LayoutElement* right = panel->addRight(200);

  right->addLeft(12, sepData);
  right->addTop(23, lblType);
  right->addTop(23, hComboType)->margins.bottom = 8;

  elemData = right->addFill();

  panel->addFill(picTexture);
  panel->margins.top = 10;

  addOKCancel(btnOK, btnCancel, sepButtons);
}

VOID    EditTexture::onCommand(Event::CommandEvent& iEvent)
{
  if (iEvent.control == hComboType && iEvent.code == CBN_SELCHANGE)
    updateTypeData();
}

VOID EditTexture::onNotify(Event::NotifyEvent& iEvent)
{
  switch (iEvent.data->idFrom)
  {
  case RETRO_TEXTUREBUTTON_ID:
    if (GetOpenFileName(&open))
    {
      SetWindowText(hEditPath, path);
      isNewTexture = TRUE;

      picTexture.setTexture(newBitmap = new Gdip::Bitmap(path));
      picTexture.invalidate(FALSE);
    }
    break;
  case IDOK:
    setResult(DialogOK);
  case IDCANCEL:
    hide();
    break;
  }
}

VOID    EditTexture::updateTypeData()
{
  LayoutElement* panel;

  elemData->clear();

  switch (textureTypesVal[ComboBox_GetCurSel(hComboType)])
  {
  case Data::TextureImage:
    break;
  case Data::TextureTileset:
    SendMessage(hUpDownData1, UDM_SETRANGE32,
      RETRO_GRIDMAP_MINTILESIZE,
      RETRO_GRIDMAP_MAXTILESIZE);
    SendMessage(hUpDownData1, UDM_SETPOS32, 0,
      RETRO_GRIDMAP_DEFTILESIZE);

    lblData1.setText(_T("Tile Size:"));

    panel = elemData->addTop(23);
    panel->addRight(20, hUpDownData1);
    panel->addRight(75, hEditData1);
    panel->addFill(lblData1);
    break;
  case Data::TextureAnimation:
    SendMessage(hUpDownData1, UDM_SETRANGE32, 1, 1000);
    SendMessage(hUpDownData1, UDM_SETPOS32, 0, 32);
    SendMessage(hUpDownData2, UDM_SETRANGE32, 1, 1000);
    SendMessage(hUpDownData2, UDM_SETPOS32, 0, 32);

    lblData1.setText(_T("Frame Width:"));
    lblData2.setText(_T("Frame Height:"));

    panel = elemData->addTop(23);
    panel->addRight(20, hUpDownData1);
    panel->addRight(75, hEditData1);
    panel->addFill(lblData1);

    panel = elemData->addTop(23);
    panel->addRight(20, hUpDownData2);
    panel->addRight(75, hEditData2);
    panel->addFill(lblData2);
    break;
  }

  SetWindowPos(hComboType, btnPath, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
  SetWindowPos(hEditData1, hComboType, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
  SetWindowPos(hEditData2, hEditData1, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);

  doLayout();
}

VOID    EditTexture::newTexture()
{
  TCHAR szName[RETRO_MAXTEXT];

  _stprintf(szName, _T("Texture %.4d"),
    Frame::get()->getProject().getNextResourceID(Data::ResourceTexture));

  SetWindowText(hEditName, szName);
  SetWindowText(hEditPath, _T(""));
  ComboBox_SetCurSel(hComboType, 0);

  picTexture.setTexture(NULL);
  updateTypeData();

  isNewTexture = FALSE;
  setText(_T("New Texture"));
}

VOID    EditTexture::setTexture(Data::Texture* value)
{
  INT typeIndex;

  Array_FindIndex(typeIndex, value->getTextureType(), textureTypesVal);
  ComboBox_SetCurSel(hComboType, typeIndex);

  updateTypeData();

  switch (value->getTextureType()) {
  case Data::TextureImage:
    break;
  case Data::TextureTileset:
    SendMessage(hUpDownData1, UDM_SETPOS32, 0,
      value->getDataTileset().tileSize);
    break;
  case Data::TextureAnimation:
    SendMessage(hUpDownData1, UDM_SETPOS32, 0,
      value->getDataAnimation().cx);
    SendMessage(hUpDownData2, UDM_SETPOS32, 0,
      value->getDataAnimation().cy);
    break;
  }

  SetCurrentDirectory(GetResourceFolder(value->getType()));

  GetCurrentDirectory(MAX_PATH, path);
  _tcscat(path, _T("\\"));
  _tcscat(path, value->getPath());

  SetWindowText(hEditPath, path);
  SetWindowText(hEditName, value->getName());

  picTexture.setTexture(value->getBitmap());
  newBitmap = NULL;

  isNewTexture = FALSE;
  SetCurrentDirectory(_T("..\\"));
  setText(_T("Texture Properties"));
}

VOID    EditTexture::getTexture(Data::Texture* value)
{
  TCHAR szName[RETRO_MAXNAME];

  Edit_GetText(hEditName, szName, RETRO_MAXNAME);
  Edit_GetText(hEditPath, path, MAX_PATH);

  value->setName(szName);
  value->setTextureType(textureTypesVal[ComboBox_GetCurSel(hComboType)]);

  switch (value->getTextureType())
  {
  case Data::TextureImage:
    break;
  case Data::TextureTileset:
    value->getDataTileset().tileSize = (INT)SendMessage(
      hUpDownData1, UDM_GETPOS32, 0, NULL);
    break;
  case Data::TextureAnimation:
    value->getDataAnimation().cx = (INT)SendMessage(
      hUpDownData1, UDM_GETPOS32, 0, NULL);
    value->getDataAnimation().cy = (INT)SendMessage(
      hUpDownData2, UDM_GETPOS32, 0, NULL);
    break;
  }

  if (isNewTexture) value->setPath(path);
}
